#pragma once

#include"RBTree.h"

namespace wgm
{
  template<class K, class V>
    class map{
      struct MapKeyOfT
      {
        const K& operator()(const pair<K, V>& kv)
        {
          return kv.first;
        }
      };

      public:
      typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::Iterator iterator;
      typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::ConstIterator const_iterator;
      
      iterator begin()
      {
        return _rbtree.Begin(); 
      }

      iterator end()
      {
        return _rbtree.End();
      }
      
      const_iterator begin() const
      {
        return _rbtree.Begin();
      }

      const_iterator end() const
      {
        return _rbtree.End();
      }

      pair<iterator, bool> insert(const pair<K, V>& kv)
      {
        return _rbtree.Insert(kv);
      }

      V& operator[](const K& key)
      {
        pair<iterator, bool> ret = _rbtree.Insert({key, V()});
        return ret.first->second;
      }

      iterator find(const K& key)
      {
        return _rbtree.Find(key);
      }

      private:
      RBTree<K, pair<const K, V>, MapKeyOfT> _rbtree;
    };

    void test_map()
    {
      map<int, int> m;
      m.insert({1, 1});
      m.insert({5, 5});
      m.insert({2, 2});
      m.insert({6, 6});
      map<int, int>::iterator it = m.begin();
      while(it != m.end())
      {
        it->second += 1;
        cout << it->first << ":" << it->second << endl;
        ++it;
      }
    }

}

